package msgpack

import (
	"errors"

	"sieve_admin_server_userpass/pkg/json"
)

//

type Req struct {
	Name   string
	Data   json.RawMessage
	Caller string `json:",omitempty"`
}

func NewReq(name string, data interface{}) ([]byte, error) {
	return NewReqWithCaller(name, data, "")
}

func NewReqWithCaller(name string, data interface{}, caller string) ([]byte, error) {
	p := &Req{Name: name, Caller: caller}
	b, err := json.Marshal(data)
	if err != nil {
		return nil, err
	}
	p.Data = json.RawMessage(b)
	return json.Marshal(p)
}

func ParseReq(data []byte) (*Req, error) {
	p := &Req{}
	if err := json.Unmarshal(data, &p); err != nil {
		return nil, err
	}
	return p, nil
}

func (r *Req) Parse(v interface{}) error {
	return json.Unmarshal(r.Data, &v)
}

type Resp struct {
	Data json.RawMessage
	Err  string
}

func NewResp(data interface{}) ([]byte, error) {
	p := &Resp{}
	if e, ok := data.(error); ok {
		p.Err = e.Error()
	} else {
		if b, err := json.Marshal(data); err != nil {
			p.Err = err.Error()
		} else {
			p.Data = json.RawMessage(b)
		}
	}
	return json.Marshal(p)
}

func ParseResp(data []byte, v interface{}) error {
	p := &Resp{}
	if err := json.Unmarshal(data, &p); err != nil {
		return err
	}
	if p.Err != "" {
		return errors.New(p.Err)
	}
	return json.Unmarshal(p.Data, &v)
}
